package org.itydl.game.model

import org.itheima.kotlin.game.core.Painter
import org.itydl.game.Config
import org.itydl.game.business.*
import org.itydl.game.enums.Direction
import java.util.*

/**
 * 地方坦克
 * 可以移动的(避开阻挡物)
 * 可以自由移动的(自由移动)
 */
class Enemy(override var x: Int, override var y: Int) :
        AutoMovable, Movable, Blockable, AutoShot, Sufferable, Destoryable { // 自己不能穿透自己，自己也是阻挡物，可自动射击，遭受攻击，销毁能力

    override var currentDirection: Direction = Direction.DOWN
    override val speed: Int = 3
    override val width: Int = Config.block
    override val height: Int = Config.block

    /**
     * 发生碰撞的方向
     */
    private var currentBadDirection: Direction? = null

    /**
     * 上一次发射完子弹的时间
     */
    private var lastShotTime: Long = 0
    /**
     * 1s发射一次子弹
     */
    private val shotFrequency = 1000

    /**
     * 敌方坦克的血量
     */
    override var blood: Int = 2

    /**
     * 地方坦克需要根据【方向】绘制
     */
    override fun draw() {
        val imagePath = when (currentDirection) {
            Direction.UP -> "img/enemy_1_u.gif"
            Direction.DOWN -> "img/enemy_1_d.gif"
            Direction.LEFT -> "img/enemy_1_l.gif"
            Direction.RIGHT -> "img/enemy_1_r.gif"
        }
        Painter.drawImage(imagePath, x, y)
    }

    /**
     * 自动移动
     */
    override fun autoMove() {

        if (currentDirection == currentBadDirection) {
            // 当前移动坦克发生碰撞，应该随机改变坦克的方向
            currentDirection = changeDirection(currentBadDirection)
            // 碰撞，停止再往该方向移动
            return
        }

        // 移动坦克
        when (currentDirection) {
            Direction.UP -> y -= speed
            Direction.DOWN -> y += speed
            Direction.LEFT -> x -= speed
            Direction.RIGHT -> x += speed
        }

        // 处理越界--画图理解
        if (x < 0) x = 0
        if (x > Config.gameWidth - width) x = Config.gameWidth - width
        if (y < 0) y = 0
        if (y > Config.gameHeight - height) y = Config.gameHeight - height
    }

    /**
     * 通知敌军坦克跟谁发生了碰撞
     */
    override fun notifyCollication(direction: Direction?, blockable: Blockable?) {
        currentBadDirection = direction
    }

    /**
     * 发生了碰撞，改变坦克的方向，不能再是传入的阻塞的方向了
     */
    private fun changeDirection(badDirection: Direction?): Direction {
        // 四个方向，产生4个随机数
        val i = Random().nextInt(4)
        // 随机生成方向
        val direction = when (i) {
            0 -> Direction.UP
            1 -> Direction.DOWN
            2 -> Direction.LEFT
            3 -> Direction.RIGHT
            else -> Direction.DOWN
        }
        if (direction == badDirection) {
            // 如果随机一次后方向仍然没变，则重新走一遍
            return changeDirection(badDirection)
        }
        return direction
    }

    override fun autoShot(): View? {
        val current = System.currentTimeMillis()
        if (current - lastShotTime < shotFrequency) return null
        lastShotTime = current
        // this表示该子弹是地方子弹发射出去的
        return Bullet(this, currentDirection) { bulletWidth, bulletHeight ->
            // 闭包是最后一个参数，应该放在后面，该函数在Bullet中调用
            // 函数入参bulletWidth,bulletHeight，-> 最后一行为返回值
            val tankWidth: Int = width
            val tankHeight: Int = height

            val tankX: Int = x
            val tankY: Int = y

            var bulletX = 0
            var bulletY = 0
            when (currentDirection) {
                Direction.UP -> {
                    // bulletWidth和bulletHeight应该由子弹传递过来
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY - bulletHeight / 2
                }

                Direction.DOWN -> {
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY + tankHeight - bulletHeight / 2
                }

                Direction.LEFT -> {
                    bulletX = tankX - bulletWidth / 2
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }

                Direction.RIGHT -> {
                    bulletX = tankX + tankWidth - bulletWidth / 2
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }
            }
            // 闭包的返回值类型是 Pair
            Pair<Int, Int>(bulletX, bulletY)
        }
    }

    override fun notifySuffered(attackable: Attackable): Array<View>? {
        // 不减血量--如果该攻击者是自动射击物体（自动射击物体属于敌方的）
        if (attackable.from is AutoShot) {
            return null
        }
        blood -= attackable.power
        return arrayOf(Blast(x, y))
    }

    override fun isDestory(): Boolean {
        return blood <= 0
    }
}